package com.wangwei.modules.servlet

import com.alibaba.fastjson.JSON
import com.wangwei.modules.servlet.spring.Controller
import com.wangwei.modules.servlet.spring.HandlerInterceptor
import com.wangwei.modules.servlet.spring.RequestMapping
import com.wangwei.modules.utils.HttpResponseUtil.ContentType
import com.wangwei.modules.utils.ann.AnnUtil
import com.wangwei.modules.utils.method.bean.MethodInfoVO
import org.springframework.ui.RedirectAttributesModelMap
import javax.servlet.ServletRequest
import javax.servlet.ServletResponse
import javax.servlet.http.HttpServlet
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
import com.wangwei.modules.servlet.interceptor.MyInterceptor

/**
 *spring的servlet
 */
class DispatcherServlet : HttpServlet {
	
	

	constructor() : super() {
		//初始化组件
		ComponentFactory.initAllComponent("com.wangwei.modules")
		//依赖注入
		ComponentFactory.autowiredAll();
		//初始化servlet
		initSpringServlet()
		//加入拦截器
		interceptors.add(MyInterceptor())
	}

	//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/  Dispatcher部分  _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

	//所有可被调用的方法存储位置
	var pathVoMap = hashMapOf<String, MethodInfoVO>();

	//根据路径获取方法
	fun getSpringMethodByPath(path: String): MethodInfoVO? = pathVoMap[path]

	//初始化所有springservlet
	fun initSpringServlet() {
		var muitServletMap: HashMap<String, MethodInfoVO> = HashMap<String, MethodInfoVO>();//path,方法信息
		for ((clazz, clazzInstance) in ComponentFactory.classComponentMap) {
			if (AnnUtil.checkClassHasAnn(clazz, Controller::class.java)) {
				//获取带有注解的方法
				var lms = AnnUtil.getAnnMethodInfo(clazz.name, RequestMapping::class.java);
				for (mVo in lms) {
					//放置方法
					muitServletMap.put(mVo.getPath(), mVo.setMethodClass(clazzInstance));
				}
			}
			pathVoMap.putAll(muitServletMap);
		}
	}

	//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/  拦截器部分  _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
	var interceptors = arrayListOf<HandlerInterceptor>();


	override fun service(request: ServletRequest, responce: ServletResponse) {
		if (request is HttpServletRequest && responce is HttpServletResponse) {

			//进controller
			var methodVO = getSpringMethodByPath(request.url);
			if (methodVO != null) {
				var exp: Exception? = null;
				//拦截器预处理
				for (interceptor in interceptors) {
					interceptor.preHandle(request, responce, methodVO)
				}
				//执行方法
				if (methodVO.isReturn2Page) {//有返回页面
					try {
						var model = RedirectAttributesModelMap();
						var url = methodVO.invoke(request.paremeters, model)
						responce.location("" + url, model)
					} catch (e: Exception) {
						exp = e
					}
					//拦截器后处理
					for (interceptor in interceptors) {
						interceptor.afterCompletion(request, responce, methodVO, exp)
					}
					if (exp == null) return
				} else {
					try {
						var res = methodVO.invoke(request.paremeters, null)
						var resStr: String? = null
						if (res is String) {
							resStr = res;
						} else if (res is Integer) {
							resStr = "" + res
						} else {
							var str: String = res.toString()
							try {
								str = JSON.toJSON(res).toString()
							} catch (e: Exception) {
							}
							resStr = str
						}
						responce.output(resStr, ContentType.html)
						println("RETURN " + resStr)
					} catch (e: Exception) {
						exp = e
					}
					for (interceptor in interceptors) {
						interceptor.afterCompletion(request, responce, methodVO, exp)
					}
					if (exp == null) return
				}
			}
			throw Exception()
		}


	}
}